using System;
using System.Text;

// string encoding complete

namespace csammisrun.OscarLib.Utility
{
	/// <summary>
	/// Provides static methods for processing messages in SNAC family 0x000B -- statistic reporting service
	/// </summary>
	internal static class SNAC0B
	{
    /// <summary>
		/// Processes the reporting interval alert -- SNAC(0B,02)
		/// </summary>
		/// <param name="dp">A <see cref="DataPacket"/> object containing SNAC(0B,02)</param>
		public static void ProcessReportingInterval(DataPacket dp)
		{
			Session sess = dp.ParentSession;
			byte[] SNACData = dp.Data;

			ushort interval = Marshal.ByteArrayToUshort(SNACData, 0);

			dp.ParentSession.OnReportingIntervalReceived(interval);
		}

		/// <summary>
		/// Sends a status report to the OSCAR server -- SNAC(0B,03)
		/// </summary>
		/// <param name="sess">A <see cref="Session"/> object</param>
		/// <remarks>libfaim does not send this report</remarks>
		public static void SendStatusReport(Session sess)
		{
			SNACHeader sh = new SNACHeader();
			sh.FamilyServiceID = (ushort)SNACFamily.UsageStatsService;
			sh.FamilySubtypeID = (ushort)UsageStatsService.UsageReport;
			sh.Flags = 0;
			sh.RequestID = sess.GetNextRequestID();

			// Get the necessary strings together
			string sn = sess.ScreenName;
			// Here we start lying until I can figure out how to get *all* the values in .NET
			string osversion = Environment.OSVersion.ToString();
			string osname = "Windows 98"; //osversion.Substring(0, osversion.LastIndexOf(" ") - 1);
			string osver = "4.10.67766446"; //osversion.Substring(osversion.LastIndexOf(" ") + 1);
			string procname = "Intel Pentium";
			string winsockname = "Microsoft Corporation BSD Socket API for Windows";
			string winsockver = "4.1.1998";

      Encoding enc = Marshal.ASCII;
      byte snlength = (byte)enc.GetByteCount(sn);
      ushort osversionlength = (ushort)enc.GetByteCount(osversion);
      ushort osnamelength = (ushort)enc.GetByteCount(osname);
      ushort osverlength = (ushort)enc.GetByteCount(osver);
      ushort procnamelength = (ushort)enc.GetByteCount(procname);
      ushort winsocknamelength = (ushort)enc.GetByteCount(winsockname);
      ushort winsockverlength = (ushort)enc.GetByteCount(winsockver);

			byte[] buffer = new byte[24 + 1 + snlength + 4 + osnamelength + 2 + 
				osverlength + 2 + procnamelength + 2 + winsocknamelength + 2 + 
				winsockverlength + 12];

			int index = 0;
			TimeSpan t = (DateTime.Now - new DateTime(1970, 1, 1));
			Marshal.InsertUint(buffer, (uint)t.Seconds, ref index);
			t = (DateTime.UtcNow - new DateTime(1970, 1, 1).ToUniversalTime());
			Marshal.InsertUint(buffer, (uint)t.Seconds, ref index);

			Marshal.InsertUint(buffer, 0x0000000, ref index);
			Marshal.InsertUint(buffer, 0x0000000, ref index);
			Marshal.InsertUint(buffer, 0x0000000, ref index);
			Marshal.InsertUint(buffer, 0x0000000, ref index);

			buffer[index++] = snlength;
      Marshal.InsertString(buffer, sn, enc, ref index);
			Marshal.InsertUshort(buffer, osnamelength, ref index);
      Marshal.InsertString(buffer, osname, enc, ref index);
			Marshal.InsertUshort(buffer, osverlength, ref index);
      Marshal.InsertString(buffer, osver, enc, ref index);
			Marshal.InsertUshort(buffer, procnamelength, ref index);
      Marshal.InsertString(buffer, procname, enc, ref index);
			Marshal.InsertUshort(buffer, winsocknamelength, ref index);
      Marshal.InsertString(buffer, winsockname, enc, ref index);
			Marshal.InsertUshort(buffer, winsockverlength, ref index);
      Marshal.InsertString(buffer, winsockver, enc, ref index);

			Marshal.InsertUint(buffer, 0x00000002, ref index);
			Marshal.InsertUint(buffer, 0x00010001, ref index);
			Marshal.InsertUint(buffer, 0x00020002, ref index);

			DataPacket dp = Marshal.BuildDataPacket(sess, sh,
				TLVMarshal.TLVsToByteArray(new TLV[] {TLVMarshal.MakeTLV(0x0009, buffer)} ));
			SNACFunctions.BuildFLAP(dp);
		}

		/// <summary>
		/// Processes the statistic report acknowledgement -- SNAC(0B,04)
		/// </summary>
		/// <param name="dp">A <see cref="DataPacket"/> object containing SNAC(0B,04)</param>
		public static void ProcessReportAcknowledgement(DataPacket dp)
		{
			Session sess = dp.ParentSession;
			byte[] SNACData = dp.Data;

			// Well...that's it. This SNAC is empty.
		}
	}
}
